package com.scott.itcast.thread.pool.p05.callableandfuture;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.junit.Test;

/**
 * 启动1个线程。然后那个线程运行完毕后返回1个结果。我们可以获得那个线程执行完毕后的返回的结果
 */
public class CallableAndFuture {
	
	@Test
	public void  submit(){
		//线程池 单一线程池  
		ExecutorService threadPool = Executors.newSingleThreadExecutor();
		//让线程池执行1个任务  这里要得到返回的结果  所以用提交任务
		Future<String> future =threadPool.submit(new Callable<String>(){
			public String call() throws Exception {
				//先休息2秒钟
				Thread.sleep(5*1000);
				return "hello";
			}
		});
		//得到结果
		try {
			System.out.println("开始等待结果....");
			String jieguo  =future.get();
			System.out.println(jieguo);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	}//end
	
	
	/**
	 * 在固定的时间内返回结果
	 */
	@Test
	public void  submit2(){
		//线程池 单一线程池  
		ExecutorService threadPool = Executors.newSingleThreadExecutor();
		//让线程池执行1个任务  这里要得到返回的结果  所以用提交任务
		Future<String> future =threadPool.submit(new Callable<String>(){

			public String call() throws Exception {
				//先休息2秒钟
				Thread.sleep(5*1000);
				return "hello";
			}
			
		});
		//得到结果
		try {
			System.out.println("开始等待结果....");
			String jieguo  =future.get(6,TimeUnit.SECONDS);
			System.out.println(jieguo);
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	
	
	/**
	 * 利用线程池执行1组任务  执行10个任务
	 * 典型的运用 QQ农场  
	 */
	@Test
	public void completionService() throws Exception{
		
		//具有10个线程的 线程池
		ExecutorService threadPool = Executors.newFixedThreadPool(10);
		
		//ExecutorCompletionService 
		//然后把10个线程交给ExecutorCompletionService去运行。
		//ExecutorCompletionService可以执行1组任务
		//ExecutorCompletionService 执行任务返回的结果是Integer
		CompletionService<Integer> completionService= new ExecutorCompletionService<Integer>(threadPool);
		
		for(int i =1; i<=10; i++){
			final int counter = i;
			
			//在这里相当于种了10块地的麦子
			completionService.submit(new Callable<Integer>() {
				public Integer call() throws Exception {
					
					//任务之间间隔1段时间  每个任务之间最多相差5秒  5000毫秒
					Thread.sleep(new Random().nextInt(5000));
					
					System.out.println("执行的线程名称：["+Thread.currentThread().getName()+"]。执行第"+counter+"次循环");
					
					//返回任务的编号
					return counter;
				}
			});
		}//end for
		
		//等待收获 那块先熟了。就先收割那块麦子
		for(int jieguo=0; jieguo<10; jieguo++){
			System.out.println("那块麦子先收割"+completionService.take().get());
		}//end for
		
	}//end completionService

}
